package com.ai.imagetext.service;

import com.ai.imagetext.entity.Image;
import com.ai.imagetext.entity.TextContent;
import com.ai.imagetext.repository.ImageRepository;
import com.ai.imagetext.repository.TextContentRepository;
import com.ai.imagetext.service.AIService.TextGenerationResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class TextGenerationService {
    
    private final AIService aiService;
    private final ImageRepository imageRepository;
    private final TextContentRepository textContentRepository;
    
    /**
     * 为图片生成文案
     */
    @Transactional
    public TextContent generateTextForImage(Long imageId, TextContent.ContentType contentType, 
                                          TextContent.StyleType styleType, String customPrompt) {
        log.info("Generating text for image: {}, type: {}, style: {}", imageId, contentType, styleType);
        
        Image image = imageRepository.findByIdAndIsDeletedFalse(imageId)
                .orElseThrow(() -> new IllegalArgumentException("图片不存在或已删除"));
        
        // 检查是否已存在相同类型和风格的文案
        Optional<TextContent> existingContent = textContentRepository
                .findByImageIdAndContentTypeAndStyleTypeAndIsDeletedFalse(imageId, contentType, styleType);
        
        if (existingContent.isPresent()) {
            log.info("Text content already exists for image: {}, type: {}, style: {}", imageId, contentType, styleType);
            return existingContent.get();
        }
        
        // 创建文案记录
        TextContent textContent = new TextContent();
        textContent.setImage(image);
        textContent.setContentType(contentType);
        textContent.setStyleType(styleType);
        textContent.setPromptUsed(customPrompt);
        textContent.setAiGenerationStatus(TextContent.AIGenerationStatus.PENDING);
        textContent.setIsDeleted(false);
        
        TextContent savedContent = textContentRepository.save(textContent);
        
        // 异步生成文案
        generateTextAsync(savedContent, customPrompt);
        
        return savedContent;
    }
    
    /**
     * 异步生成文案
     */
    @Async("aiTaskExecutor")
    @Transactional
    public void generateTextAsync(TextContent textContent, String customPrompt) {
        log.info("Starting async text generation for content: {}", textContent.getId());
        
        try {
            // 调用AI服务生成文案
            TextGenerationResult result = aiService.generateText(
                    textContent.getImage().getFileUrl(),
                    textContent.getContentType().name(),
                    textContent.getStyleType().name(),
                    customPrompt
            );
            
            if (result.isSuccess()) {
                // 更新文案内容
                textContent.setContent(result.getContent());
                textContent.setAiGenerationStatus(TextContent.AIGenerationStatus.SUCCESS);
                log.info("Text generation completed successfully for content: {}", textContent.getId());
            } else {
                // 处理生成失败
                textContent.setContent("文案生成失败: " + result.getErrorMessage());
                textContent.setAiGenerationStatus(TextContent.AIGenerationStatus.FAILED);
                log.warn("Text generation failed for content: {}, error: {}", textContent.getId(), result.getErrorMessage());
            }
            
            textContentRepository.save(textContent);
            
        } catch (Exception e) {
            log.error("Unexpected error during text generation for content: {}", textContent.getId(), e);
            textContent.setContent("系统错误: " + e.getMessage());
            textContent.setAiGenerationStatus(TextContent.AIGenerationStatus.FAILED);
            textContentRepository.save(textContent);
        }
    }
    
    /**
     * 批量生成文案
     */
    @Async("aiTaskExecutor")
    @Transactional
    public void batchGenerateText(Long imageId, List<TextContent.ContentType> contentTypes, 
                                 List<TextContent.StyleType> styleTypes, String customPrompt) {
        log.info("Starting batch text generation for image: {}", imageId);
        
        Image image = imageRepository.findByIdAndIsDeletedFalse(imageId)
                .orElseThrow(() -> new IllegalArgumentException("图片不存在或已删除"));
        
        for (TextContent.ContentType contentType : contentTypes) {
            for (TextContent.StyleType styleType : styleTypes) {
                try {
                    // 检查是否已存在
                    Optional<TextContent> existing = textContentRepository
                            .findByImageIdAndContentTypeAndStyleTypeAndIsDeletedFalse(imageId, contentType, styleType);
                    
                    if (existing.isEmpty()) {
                        generateTextForImage(imageId, contentType, styleType, customPrompt);
                        
                        // 添加延迟避免API频率限制
                        Thread.sleep(1000);
                    }
                    
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    log.warn("Batch text generation interrupted for image: {}", imageId);
                    break;
                } catch (Exception e) {
                    log.error("Error in batch text generation for image: {}, type: {}, style: {}", 
                             imageId, contentType, styleType, e);
                }
            }
        }
        
        log.info("Batch text generation completed for image: {}", imageId);
    }
    
    /**
     * 重新生成文案
     */
    @Transactional
    public TextContent regenerateText(Long textContentId, String customPrompt) {
        log.info("Regenerating text for content: {}", textContentId);
        
        TextContent textContent = textContentRepository.findById(textContentId)
                .filter(tc -> !tc.getIsDeleted())
                .orElseThrow(() -> new IllegalArgumentException("文案不存在或已删除"));
        
        // 更新状态和提示词
        textContent.setAiGenerationStatus(TextContent.AIGenerationStatus.PENDING);
        textContent.setPromptUsed(customPrompt);
        TextContent savedContent = textContentRepository.save(textContent);
        
        // 异步重新生成
        generateTextAsync(savedContent, customPrompt);
        
        return savedContent;
    }
    
    /**
     * 获取图片的所有文案
     */
    public List<TextContent> getTextContentsForImage(Long imageId) {
        log.info("Getting text contents for image: {}", imageId);
        return textContentRepository.findByImageIdAndIsDeletedFalse(imageId);
    }
    
    /**
     * 根据类型和风格获取文案
     */
    public List<TextContent> getTextContentsByTypeAndStyle(TextContent.ContentType contentType, 
                                                          TextContent.StyleType styleType) {
        log.info("Getting text contents by type: {} and style: {}", contentType, styleType);
        
        if (contentType != null && styleType != null) {
            return textContentRepository.findByContentTypeAndStyleTypeAndIsDeletedFalse(contentType, styleType);
        } else if (contentType != null) {
            return textContentRepository.findByContentTypeAndIsDeletedFalse(contentType);
        } else if (styleType != null) {
            return textContentRepository.findByStyleTypeAndIsDeletedFalse(styleType);
        } else {
            return textContentRepository.findByIsDeletedFalseOrderByCreatedAtDesc(null).getContent();
        }
    }
    
    /**
     * 更新文案内容
     */
    @Transactional
    public TextContent updateTextContent(Long textContentId, String content) {
        log.info("Updating text content: {} with new content", textContentId);
        
        TextContent textContent = textContentRepository.findById(textContentId)
                .filter(tc -> !tc.getIsDeleted())
                .orElseThrow(() -> new IllegalArgumentException("文案不存在或已删除"));
        
        textContent.setContent(content);
        textContent.setUpdatedAt(LocalDateTime.now());
        
        return textContentRepository.save(textContent);
    }
    
    /**
     * 删除文案
     */
    @Transactional
    public void deleteTextContent(Long textContentId) {
        log.info("Deleting text content: {}", textContentId);
        
        TextContent textContent = textContentRepository.findById(textContentId)
                .filter(tc -> !tc.getIsDeleted())
                .orElseThrow(() -> new IllegalArgumentException("文案不存在或已删除"));
        
        textContentRepository.softDeleteById(textContentId);
    }
    
    /**
     * 批量删除图片的所有文案
     */
    @Transactional
    public void deleteAllTextContentsForImage(Long imageId) {
        log.info("Deleting all text contents for image: {}", imageId);
        textContentRepository.softDeleteByImageId(imageId);
    }
    
    /**
     * 重试失败的文案生成
     */
    @Async("aiTaskExecutor")
    @Transactional
    public void retryFailedGenerations() {
        log.info("Retrying failed text generations");
        
        List<TextContent> failedContents = textContentRepository
                .findByAiGenerationStatusAndIsDeletedFalse(TextContent.AIGenerationStatus.FAILED);
        
        log.info("Found {} failed text generation contents to retry", failedContents.size());
        
        for (TextContent content : failedContents) {
            try {
                generateTextAsync(content, content.getPromptUsed());
                
                // 添加延迟避免API频率限制
                Thread.sleep(2000);
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.warn("Retry failed text generations interrupted");
                break;
            } catch (Exception e) {
                log.error("Error retrying text generation for content: {}", content.getId(), e);
            }
        }
        
        log.info("Retry failed text generations completed");
    }
    
    /**
     * 获取文案生成统计信息
     */
    public TextGenerationStatistics getTextGenerationStatistics() {
        long totalContents = textContentRepository.count();
        long successCount = textContentRepository.countByAiGenerationStatusAndIsDeletedFalse(
                TextContent.AIGenerationStatus.SUCCESS);
        long failedCount = textContentRepository.countByAiGenerationStatusAndIsDeletedFalse(
                TextContent.AIGenerationStatus.FAILED);
        long pendingCount = textContentRepository.countByAiGenerationStatusAndIsDeletedFalse(
                TextContent.AIGenerationStatus.PENDING);
        
        long shortCount = textContentRepository.countByContentTypeAndIsDeletedFalse(
                TextContent.ContentType.SHORT);
        long longCount = textContentRepository.countByContentTypeAndIsDeletedFalse(
                TextContent.ContentType.LONG);
        
        long promotionalCount = textContentRepository.countByStyleTypeAndIsDeletedFalse(
                TextContent.StyleType.PROMOTIONAL);
        long warmCount = textContentRepository.countByStyleTypeAndIsDeletedFalse(
                TextContent.StyleType.WARM);
        long professionalCount = textContentRepository.countByStyleTypeAndIsDeletedFalse(
                TextContent.StyleType.PROFESSIONAL);
        
        TextGenerationStatistics stats = new TextGenerationStatistics();
        stats.setTotalContents(totalContents);
        stats.setSuccessCount(successCount);
        stats.setFailedCount(failedCount);
        stats.setPendingCount(pendingCount);
        stats.setSuccessRate(totalContents > 0 ? (double) successCount / totalContents * 100 : 0.0);
        stats.setShortCount(shortCount);
        stats.setLongCount(longCount);
        stats.setPromotionalCount(promotionalCount);
        stats.setWarmCount(warmCount);
        stats.setProfessionalCount(professionalCount);
        
        return stats;
    }
    
    /**
     * 文案生成统计信息
     */
    public static class TextGenerationStatistics {
        private long totalContents;
        private long successCount;
        private long failedCount;
        private long pendingCount;
        private double successRate;
        private long shortCount;
        private long longCount;
        private long promotionalCount;
        private long warmCount;
        private long professionalCount;
        
        // Getters and Setters
        public long getTotalContents() { return totalContents; }
        public void setTotalContents(long totalContents) { this.totalContents = totalContents; }
        
        public long getSuccessCount() { return successCount; }
        public void setSuccessCount(long successCount) { this.successCount = successCount; }
        
        public long getFailedCount() { return failedCount; }
        public void setFailedCount(long failedCount) { this.failedCount = failedCount; }
        
        public long getPendingCount() { return pendingCount; }
        public void setPendingCount(long pendingCount) { this.pendingCount = pendingCount; }
        
        public double getSuccessRate() { return successRate; }
        public void setSuccessRate(double successRate) { this.successRate = successRate; }
        
        public long getShortCount() { return shortCount; }
        public void setShortCount(long shortCount) { this.shortCount = shortCount; }
        
        public long getLongCount() { return longCount; }
        public void setLongCount(long longCount) { this.longCount = longCount; }
        
        public long getPromotionalCount() { return promotionalCount; }
        public void setPromotionalCount(long promotionalCount) { this.promotionalCount = promotionalCount; }
        
        public long getWarmCount() { return warmCount; }
        public void setWarmCount(long warmCount) { this.warmCount = warmCount; }
        
        public long getProfessionalCount() { return professionalCount; }
        public void setProfessionalCount(long professionalCount) { this.professionalCount = professionalCount; }
    }
}
